<?php


namespace PKApp\DataBase;


use PKApp\Content\Classes\CategoryService;
use PKApp\Content\Classes\ContentService;
use PKApp\Content\Classes\PageService;
use PKApp\DataBase\Classes\DataBaseController;
use PKApp\DataBase\Classes\SQLiteService;
use PKApp\Model\Classes\FieldService;
use PKApp\Model\Classes\OptionsService;
use PKApp\Poster\Classes\ImageService;
use PKApp\Poster\Classes\PosterService;
use PKApp\Site\Classes\SiteService;
use PKFrame\DataHandler\Arrays;
use PKFrame\DataHandler\Numbers;

class AdminImportSQLite extends DataBaseController
{

    private $_file_path;
    protected $table_model;
    protected const CACHE_DIR = 'importSQL';
    protected const CACHE_FILE = 'list_field';

    public function __construct()
    {
        parent::__construct();
        $this->_checkPath();
    }

    public function Main()
    {
        $list_model = $this->serviceSQLite()->getModelByContent();
        $import_model = [];
        if (Arrays::Is($list_model)) {
            foreach ($list_model as $index => $item) {
                $count_content = $this->serviceSQLite()->countContentByModel(strtolower($item['tablename']));
                if ($count_content['count'] > 0) {
                    $item['count_content'] = $count_content['count'];
                    $import_model[] = $item;
                }
            }
        }
        $this->json($import_model, count($import_model));
    }

    public function ApiImportModuleBySite()
    {
        $list_site = $this->serviceSQLite()->getSite();
        Arrays::Is($list_site) ?: $this->noticeByJson('sqlite_siteEmpty');
        $service_site = new SiteService();
        $service_site->Truncate();
        $list_new = [];
        foreach ($list_site as $index => $item) {
            unset($item['info'], $item['Site_otherCode'], $item['Site_statisticsCode']);
            $Site_Contact = unserialize($item['Site_Contact']);
            $Site_Contact['BaiDuMaps'] = '';
            if (!array_key_exists('WeChat', $Site_Contact)) {
                $Site_Contact['WeChat'] = '';
            }
            $item['Site_Contact'] = serialize($Site_Contact);
            $setting = unserialize($item['setting']);
            if ($setting['setting'] == 0) {
                unset($setting['setting']);
            }
            if ($setting['IsMobileStatics'] == 0) {
                unset($setting['IsMobileStatics']);
            }
            $item['setting'] = serialize($setting);
            $list_new[] = $item;
        }
        $service_site->BatchInsert($list_new);
        $this->json('ok');
    }

    public function ApiImportModuleByCategory()
    {
        $list_category = $this->serviceSQLite()->getCategory();
        Arrays::Is($list_category) ?: $this->noticeByJson('sqlite_categoryEmpty');
        $list_field = [
            'modelId' => 'modelid',
            'parentId' => 'parentid',
            'parentIdList' => 'arrparentid',
            'childrenIdList' => 'arrchildid',
            'info' => 'subname',
            'listSort' => 'listsort',
            'countContent' => 'total',
        ];
        $service_category = new CategoryService($this->loginUser()->SiteId);
        $service_category->Truncate();
        $list_new = [];
        foreach ($list_category as $item_category) {
            $tmp_new = [];
            foreach ($list_field as $new_field => $old_field) {
                $tmp_new[$new_field] = $item_category[$old_field];
                unset($item_category[$old_field]);
            }
            if (array_key_exists('type', $item_category)) {
                switch ($item_category['type']) {
                    case 0:
                        $tmp_new['categoryType'] = 'link';
                        $item_category['seo'] = '';
                        $item_category['template'] = '';
                        break;
                    case 1:
                        $tmp_new['categoryType'] = 'page';
                        $item_category['seo'] = '';
                        $item_category['template'] = '';
                        break;
                    case 2:
                        $tmp_new['categoryType'] = 'list';
                        break;
                }
            }
            if ($item_category['seo'] == 'Array') {
                $item_category['seo'] = '';
            }
            if (array_key_exists('setting', $item_category)) {
                if ($item_category['type'] == 2) {
                    $item_category['template'] = Arrays::Unserialize($item_category['template']);
                    $item_category['setting'] = Arrays::Unserialize($item_category['setting']);
                    $item_category['template'] = serialize(array_merge($item_category['template'], $item_category['setting']));
                }
            }
            if (array_key_exists('status', $item_category)) {
                switch ($item_category['status']) {
                    case 0:
                        $tmp_new['isShow'] = 0;
                        break;
                    case 1:
                        $tmp_new['isShow'] = 1;
                        break;
                }
                unset($item_category['status']);
            }
            unset($item_category['setting'], $item_category['type']);
            $list_new[] = array_merge($tmp_new, $item_category);
        }
        $service_category->BatchInsert($list_new);
        $this->json('ok');
    }

    public function ApiImportModuleByPage()
    {
        $list_page = $this->serviceSQLite()->getCategoryByPage();
        Arrays::Is($list_page) ?: $this->json('ok');
        // 新旧字段对照
        $oldListField_newListField = [
            'siteid' => 'siteId',
            'seotitle' => 'seoTitle',
            'seokeywords' => 'seoKeywords',
            'seodescription' => 'seoDescription',
        ];
        $listNew_page = [];
        foreach ($list_page as $item_page) {
            $tmpNew_page = [];
            foreach ($oldListField_newListField as $old_field => $new_field) {
                $tmpNew_page[$new_field] = $item_page[$old_field];
                unset($item_page[$old_field]);
            }
            unset($item_page['status']);
            $listNew_page[] = array_merge($tmpNew_page, $item_page);
        }
        $service_page = new PageService();
        $service_page->Truncate();
        $service_page->BatchInsert($listNew_page);
        $this->json('ok');
    }

    public function ApiImportModuleByModelOptions()
    {
        $list_options = $this->serviceSQLite()->getModelByOptions();
        Arrays::Is($list_options) ?: $this->json('ok');
        $listNew_options = [];
        foreach ($list_options as $item_options) {
            $item_options['listSort'] = Numbers::To($item_options['listsort']);
            unset($item_options['listsort']);
            $listNew_options[] = $item_options;
        }
        $service_options = new OptionsService();
        $service_options->Truncate();
        $service_options->BatchInsert($listNew_options);
        $this->json('ok');
    }

    public function ApiImportModuleByPoster()
    {
        $list_poster = $this->serviceSQLite()->getPoster();
        if (Arrays::Is($list_poster)) {
            $list_new_poster = $list_new_ad = [];
            $service_poster = new PosterService();
            $service_poster->Truncate();
            $service_image = new ImageService();
            $service_image->Truncate();
            foreach ($list_poster as $item_poster) {
                $list_ads = Arrays::Unserialize($item_poster['adsList']);
                $tmp_new_poster = [
                    'id' => $item_poster['id'],
                    'name' => $item_poster['name'],
                    'createTime' => TIMESTAMP,
                    'posterType' => 'image',
                ];
                foreach ($list_ads as $siteId => $list_ad) {
                    foreach ($list_ad['fileurl'] as $index => $item_url) {
                        $list_new_ad[] = [
                            'siteId' => $siteId,
                            'posterId' => $tmp_new_poster['id'],
                            'image_alt' => $item_url,
                            'image_src' => $item_url,
                            'image_url' => $list_ad['link'][$index],
                            'startTime' => TIMESTAMP,
                            'stopTime' => TIMESTAMP + (3600 * 24 * 365),
                            'createTime' => TIMESTAMP,
                        ];
                    }
                }
                $list_new_poster[] = $tmp_new_poster;
                $service_poster->BatchInsert($list_new_poster);
                $service_image->BatchInsert($list_new_ad);
            }
        }
        $this->json('ok');
    }

    public function ApiImportModelByCheckField()
    {
        $this->_getImportModelByNow();
        // 原来的数据模型
        $oldList_field = $this->serviceSQLite()->getField($this->table_model['id']);
        // 当前新的已经存在的数据模型
        if (in_array(strtolower($this->table_model['tablename']), ['article', 'product'])) {
            $nowList_field = Arrays::Column(
                $this->serviceField()->GetListByModelId($this->table_model['id']),
                'isList', 'field');
            $res_fieldList = $this->_createNewField($oldList_field, $nowList_field);
        } else {
            // 当不存在的数据模型
            $this->_createNewModel();
            $res_fieldList = $this->_createNewField($oldList_field);
        }
        $this->json($res_fieldList);
    }

    public function ApiImportModelByImportData()
    {
        $this->_getImportModelByNow();
        $page_index = Numbers::To(request()->post('page_index'));
        $list_field = request()->post('list_field');
        $oldList_content = $this->serviceSQLite()->getContentByModel($this->table_model['tablename'], $page_index);
        // 新旧字段对照
        $oldListField_newListField = [
            'siteid' => 'siteId',
            'seotitle' => 'seoTitle',
            'seokeywords' => 'seoKeywords',
            'seodescription' => 'seoDescription',
            'modelid' => 'modelId',
            'catid' => 'catId',
            'inputtime' => 'createTime',
            'updatetime' => 'updateTime',
            'listsort' => 'listSort',
            'headlines' => 'toHead',
            'totop' => 'toTop',
            'posids' => 'toPush',
            'userid' => 'userId',
        ];
        $modelField_base = ['id', 'title', 'thumb', 'template', 'url'];
        $modelField_data = ['id'];
        if (Arrays::Is($list_field)) {
            // 集中模型中所有的字段
            $listField_base = Arrays::GetKey('base', $list_field);
            $listField_data = Arrays::GetKey('data', $list_field);
            !Arrays::Is($listField_base) ?: $modelField_base = array_merge($modelField_base, $listField_base);
            !Arrays::Is($listField_data) ?: $modelField_data = array_merge($modelField_data, $listField_data);
        }
        $newList_content = $list_id = [];
        foreach ($oldList_content as $item_content) {
            $tmp_content = [];
            $list_id[] = $item_content['id'];
            foreach ($oldListField_newListField as $old_field => $new_field) {
                $tmp_content[$new_field] = $item_content[$old_field];
                unset($item_content[$old_field]);
            }
            foreach ($modelField_base as $field) {
                $tmp_content[$field] = $this->_handerFieldDataByType($field, $item_content[$field]);
            }
            $newList_content[] = $tmp_content;
        }
        $oldList_content_hits = $this->serviceSQLite()->getContentByHits($this->table_model['tablename'], implode(',', $list_id));
        foreach ($newList_content as $index => $item) {
            $item['hits'] = Numbers::To(Arrays::GetKey($item['id'], $oldList_content_hits));
            $newList_content[$index] = $item;
        }
        $oldList_content_data = $this->serviceSQLite()->getContentByData($this->table_model['tablename'], implode(',', $list_id));
        $newList_content_data = [];
        foreach ($oldList_content_data as $item) {
            $tmp_data = [];
            foreach ($modelField_data as $field) {
                $tmp_data[$field] = $this->_handerFieldDataByType($field, $item[$field]);
            }
            $newList_content_data[] = $tmp_data;
        }
        $service_content = new ContentService($this->table_model['id']);
        $page_index != 1 ?: $service_content->TruncateByContent();
        $service_content->BatchInsertByContent($newList_content, $newList_content_data);
        $this->json($list_id);
    }

    private function _handerFieldDataByType(string $field_name, $value = null): ?string
    {
        static $listCache_field;
        !empty($listCache_field) ?: $listCache_field = cache()->Tmp()->ReadByJSON(
            self::CACHE_FILE . '_' . $this->table_model['tablename'], self::CACHE_DIR);
        if (array_key_exists($field_name, $listCache_field)) {
            $entity_field = $listCache_field[$field_name];
            switch ($entity_field['formtype']) {
                case 'upload_list':
                case 'image_list':
                    $value = Arrays::Unserialize($value);
                    $tmp_value = [];
                    if (Arrays::Is($value) && array_key_exists('fileurl', $value) && Arrays::Is($value['fileurl'])) {
                        foreach ($value['fileurl'] as $index => $item) {
                            if ($entity_field['formtype'] == 'image_list') {
                                // 图片列表
                                $tmp_value[] = ['img_src' => $item, 'img_tips' => $value['filename'][$index]];
                            } else {
                                // 附件列表
                                $tmp_value[] = ['file_path' => $item, 'file_tips' => $value['filename'][$index]];
                            }
                        }
                    }
                    $value = serialize($tmp_value);
                    break;
            }
        }
        return $value;
    }

    private function _createNewModel()
    {
        $table_model = array_merge($this->table_model, [
            'modelType' => 'content',
            'tableName' => $this->table_model['tablename'],
            'setting' => ['database' => 1],
        ]);
        unset($table_model['tablename'], $table_model['count_content']);
        $this->serviceField()->ServiceByModel()->CheckTableNameAndCreate($table_model['modelType'], $table_model['tableName']);
        $this->serviceField()->ServiceByModel()->Add($table_model);
    }

    /**
     * 比较新旧字段的差异，并创建缺少的字段
     * @param array $oldList_field
     * @param array $nowList_field
     * @return array[]
     */
    private function _createNewField(array $oldList_field, array $nowList_field = []): array
    {
        // 新旧字段对照
        $oldListField_newListField = [
            'modelid' => 'modelId',
            'formtype' => 'formType',
            'isindex' => 'isList',
            'issearch' => 'isSearch',
            'isorder' => 'isOrder',
            'listsort' => 'listSort',
            'preg' => 'fieldRegular',
            'isnull' => 'isEmpty',
            'isEmpty' => 'isEmpty',
            'isfront' => 'isShow',
        ];
        $listNew_field = [];
        $resList_Field = ['base' => [], 'data' => []];
        $listCache_field = [];
        foreach ($oldList_field as $oldItem_field) {
            $listCache_field[$oldItem_field['field']] = $oldItem_field;
            if (count($nowList_field) == 0 || !array_key_exists($oldItem_field['field'], $nowList_field)) {
                /**
                 * 前者是指：新的数据模型通道，是指新的数据库没有任何的字段
                 * 后者是指：已经存在的数据模型，但不存在这个字段名的时候
                 */
                $tmp_new_field = [];
                foreach ($oldListField_newListField as $old_field => $new_field) {
                    if ($old_field == 'preg' && $oldItem_field[$old_field] == 'chinese') {
                        $tmp_new_field[$new_field] = '';
                    } elseif (array_key_exists($old_field, $oldItem_field)) {
                        $tmp_new_field[$new_field] = $oldItem_field[$old_field];
                    }
                    unset($oldItem_field[$old_field]);
                }
                unset($oldItem_field['jscode']);
                $tmp_new_field = array_merge($oldItem_field, $tmp_new_field);
                if ($tmp_new_field['isList']) {
                    $resList_Field['base'][] = $tmp_new_field['field'];
                } else {
                    $resList_Field['data'][] = $tmp_new_field['field'];
                }
                if ($tmp_new_field['formType'] == 'text') {
                    $tmp_new_field['setting'] = Arrays::Unserialize($tmp_new_field['setting']);
                }
                $this->serviceField()->CheckExistsAndCreate($tmp_new_field);
                if ($tmp_new_field['formType'] == 'text') {
                    $tmp_new_field['setting'] = serialize($tmp_new_field['setting']);
                }
                $listNew_field[] = $tmp_new_field;
            } else {
                // 判断已经存在的字段是否列表字段
                if ($nowList_field[$oldItem_field['field']]) {
                    $resList_Field['base'][] = $oldItem_field['field'];
                } else {
                    $resList_Field['data'][] = $oldItem_field['field'];
                }
            }
        }
        cache()->Tmp()->WriteByJSON(self::CACHE_FILE . '_' . $this->table_model['tablename'],
            $listCache_field, self::CACHE_DIR);
        $this->serviceField()->BatchInsert($listNew_field);
        $this->serviceField()->saveCache($this->table_model['id']);
        return $resList_Field;
    }

    private function _getImportModelByNow()
    {
        $index = $this->checkPostFieldIsEmpty('index', 'sqlite_model_index_empty');
        $index_table = Numbers::To(Arrays::GetKey('table', $index));
        $table = $this->checkPostFieldIsEmpty('table', 'sqlite_model_table_empty');
        $table_list = Arrays::GetKey('lists', $table, 'sqlite_model_tableList_noExists');
        $this->table_model = Arrays::GetKey($index_table, $table_list, 'sqlite_model_tableEach_error');
    }

    private function _checkPath()
    {
        $this->_file_path = $this->getPathSQLite() . request()->post('file_name');
        file_exists($this->_file_path) ?: $this->noticeByJson('sqlite_noExists');
    }

    protected function serviceField(): FieldService
    {
        static $cls;
        !empty($cls) ?: $cls = new FieldService();
        return $cls;
    }

    protected function serviceSQLite(): SQLiteService
    {
        static $cls;
        !empty($cls) ?: $cls = new SQLiteService($this->_file_path);
        return $cls;
    }

}